﻿using Dyao.Book.Application.Abstractions;
using Dyao.Book.Core;
using Foundation.Core;

namespace Dyao.Book.Application
{
    /// <summary>
    /// 综合规则执行
    /// </summary>
    public class CompositeTaskRuleExcutor : ITaskRuleExcutor, ITransientDependency
    {
        private readonly ITaskCenterRuleApplication _taskCenterRuleService;
        private readonly IServiceProvider _serviceProvider;

        public const string RuleKey = "CompositeTaskRule";
        public string Key => RuleKey;

        public CompositeTaskRuleExcutor(ITaskCenterRuleApplication taskCenterRuleService, IServiceProvider serviceProvider)
        {
            this._taskCenterRuleService = taskCenterRuleService;
            this._serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 执行所有规则
        /// </summary>
        /// <param name="context">context</param>
        /// <returns></returns>
        public async Task ExcuteAsync(TaskCenterRuleExcutingContext context)
        {
            var compositeCotnext = context as CompositeTaskCenterRuleExcutingContext;
            var excuteList = new List<(ExcutingInfo, ITaskRuleExcutor)>();
            var taskCenterRuleList = await _taskCenterRuleService.GetTaskCenterRuleModelListAsync(compositeCotnext.RuleIds);
            if (taskCenterRuleList == null) return;

            foreach (var taskCenterRule in taskCenterRuleList)
            {
                var key = taskCenterRule.RuleKey;
                var taskCenterRuleExcutingInfo = TaskCenterRuleManager.GetRuleExcutorTypeByKey(key);
                if (taskCenterRuleExcutingInfo == null) throw new BusinessException(CommonExceptionCode.TaskCenterRuleExcutorNotFound, $"找不到key={key}的规则。");

                var info = new ExcutingInfo
                {
                    ServiceProvider = _serviceProvider,
                    RuleExecutorType = taskCenterRuleExcutingInfo.Type,
                    RuleDisplayName = taskCenterRuleExcutingInfo.Name,
                    RuleSettings = taskCenterRule.RuleSettings
                };

                var ruleExcutor = (ITaskRuleExcutor)info.ServiceProvider.GetService(info.RuleExecutorType);

                if (ruleExcutor is ITaskRuleSettingsLoader loader)
                {
                    if (string.IsNullOrWhiteSpace(info.RuleSettings))
                    {
                        throw new BusinessException(CommonExceptionCode.TaskCenterCreateRecordTaskSettingNotFound, $"{info.RuleDisplayName}的RuleSettings为空");
                    }

                    loader.LoadSettings(info.RuleSettings);
                }

                excuteList.Add((info, ruleExcutor));
            }

            foreach (var (info,executor) in excuteList)
            {
                var excuteContext = new TaskCenterRuleExcutingContext()
                {
                    Parameters = context.Parameters,
                    TaskCode =context.TaskCode,
                    Category =context.Category,
                    RuleId = info.Id,
                    RuleDisplayName =info.RuleDisplayName
                };

                await executor.ExcuteAsync(excuteContext);
            }
        }

        private class ExcutingInfo
        {
            public IServiceProvider ServiceProvider { get; set; }
            public int Id { get; set; }

            public Type RuleExecutorType { get; set; }

            public string RuleDisplayName { get; set; }

            public string RuleSettings { get; set; }

        }
    }

    /// <summary>
    /// 综合任务执行
    /// </summary>
    public class CompositeTaskCenterRuleExcutingContext : TaskCenterRuleExcutingContext
    {
        public List<int> RuleIds { get; set; }
    }
}
